Cache stampede (also known as dog-piling or cache miss storm) is a phenomenon where multiple concurrent requests for the same piece of data all miss the cache simultaneously due to expiration, overwhelming the backend database with redundant queries.
Cache stampede, also referred to as dog-piling or cache miss storm, is a common performance anti-pattern in caching systems. It occurs when a cached item expires (or is invalidated) and a large number of concurrent requests for that same item all miss the cache at the same time. This causes every request to hit the backend database or origin server simultaneously, leading to a massive spike in load that can overwhelm the system, cause high latency, or even trigger a cascading failure.
Stale-While-Revalidate (SWR): Serve stale cached data while asynchronously refreshing the cache in the background. The first request after expiry triggers a refresh, but subsequent requests receive the stale data (not a miss). This is implemented in Next.js ISR and many CDNs.
Request Coalescing (Request Deduplication): When a cache miss occurs, only the first request goes to the backend; subsequent identical requests wait for the first request's result. Implement using a mutex or a promise cache (e.g., p-limit, async-mutex, or a simple Map of in-flight promises).
Probabilistic Early Expiration (PEE): Instead of letting all cached items expire at exactly the same time, a small percentage of requests are allowed to refresh the cache early (e.g., when the TTL is 90% expired), preventing a stampede at 100% expiry.
Jittered Expiration: Add random variation to cache expiration times (TTL = baseTTL + random(0, jitter)), preventing multiple keys from expiring simultaneously.
Locking (Mutex): Acquire a lock on the cache key when a miss occurs. Only the request holding the lock can regenerate the cache; others wait or receive stale data.
ISR with stale-while-revalidate: Next.js automatically implements the stale-while-revalidate pattern. When a page's revalidate time is reached, the first request triggers background regeneration, but subsequent requests receive the stale (cached) page, not a cache miss.
fetch Deduplication: Next.js automatically deduplicates identical fetch requests that occur within the same render pass, preventing redundant network calls.
Data Cache with Tags: On-demand revalidation (revalidateTag/revalidatePath) provides granular invalidation, preventing mass cache expiry stampedes by updating only affected data.